package com.cskaoyan.javase.oop1._11static._2compare;

/**
 * 当我们了解static成员的特点后，静态成员和非静态成员的区别就很明显
 *
 * 我们从以下四个角度比较（拿成员变量为例）
 *
 * 所属不同
 *      1.静态成员变量属于类，所以也称为为类变量
 *      2.（普通）成员变量属于对象，所以也称为对象变量（实例变量）
 *
 *
 * 在内存中的位置不同
 *      1.静态变量存储于堆上(Java8中),被所有对象共享
 *      2.成员变量存储于堆内存，每个对象独享自己的成员变量
 *          成员变量直接存储在对象当中
 *
 * 在内存中出现时间不同
 *      1.静态变量随着类的加载而创建，比成员变量出现的要早(一定要更早)
 *      2.成员变量随着对象的创建而存在
 *      谁先谁后?
 *      静态成员变量一定在前,成员变量一定在后.
 *
 * 调用方式不同
 *      1.静态变量可以通过类名调用，也可以通过对象调用（禁止这种方式）
 *      2.成员变量只能通过对象名调用，必须创建对象
 *
 * 成员方法和静态成员有什么区别呢?
 *      成员方法中可以访问静态成员吗?
 *          可以,因为成员方法如果调用,对象一定存在,类加载一定进行了,静态成员肯定存在
 *
 *      静态成员方中可以访问非静态成员吗?
 *          不可用,因为只要类加载就可以调用静态成员方法了,但是类加载不一定创建对象
 *          没有对象,就无法访问非静态成员
 *          静态成员方法中没有this也就是这个原因
 *
 *      先存在的,不能访问后存在的
 *      但是后存在可以访问先存在的
 *
 * 补充:
 * 成员变量的赋值和静态成员变量的赋值
 * 两个问题:
 *      1,成员变量的赋值能不能依赖于类加载过程中的结构?比如静态成员方法
 *          不能,因为静态成员方法执行只需要类加载之后就可以了,不能依赖
 *      2,静态成员变量的赋值能不能依赖于创建对象的过程?比如成员方法,比如构造器
 *          可以,因为创建对象,静态成员变量一定存在
 *          当然具体情况具体分析,一般来说,静态成员变量尽量不要依赖于创建对象赋值
 *
 * @since 10:23
 * @author wuguidong@cskaoyan.onaliyun.com
 */
public class Demo {
    /*static int a;
    int b;

    public void test() {
        System.out.println(a);
        testStatic();
        System.out.println(b);
        test2();
    }

    public void test2() {
    }

    public static void testStatic() {
        System.out.println(a);
        // System.out.println(b);
        // test();
        testStatic2();
    }

    public static void testStatic2() {
    }*/

    public static void main(String[] args) {
        A a = new A();
        a.test();
        System.out.println(A.num);
    }
}

class A {
    // 静态成员变量的显式赋值是在类加载过程中执行的
    static int num = 1000;

    /*
        以下创建对象过程中的赋值
        一定晚于类加载过程中的赋值
        会覆盖掉类加载过程中的赋值
     */
    public void test() {
        num = 100;
    }

    public A() {
        num = 200;
    }
}